﻿//
// Copyright (c) 2024 BPer
//
#include <bperrtp/BPerRtcpCommon.h>

#include <bperrtp/BPerRtcpRR.h>
#include <bperrtp/BPerRtcpSR.h>
#include <bperrtp/BPerRtcpSli.h>
#include <bperrtp/BPerRtcpNack.h>
#include <bperrtp/BPerRtcpTWCC.h>
#include <bperrtp/BPerRtcpRpsi.h>

#include <bperutil/sys/BPerLog.h>

int32_t bPer_decode_rtcpCommon(BPerRtcpCommon* comm,BPerBuffer *buffer){
	if(comm==NULL||buffer==NULL) return 1;
	if (!bPer_buffer_require(buffer,BPer_RtcpHeader_Length + 4)) {
	        return bPer_error_wrap(ERROR_RTC_RTCP, "require %d", BPer_RtcpHeader_Length + 4);
	    }

    bPer_decode_rtcpHeader(&comm->header,buffer->head);
    bPer_buffer_skip(buffer,BPer_RtcpHeader_Length);

    int32_t payload_len = comm->header.length * 4;
    if (payload_len > bPer_buffer_left(buffer)) {
        return bPer_error_wrap(ERROR_RTC_RTCP,
                "payload require payload len=%u, buffer left=%u", payload_len, bPer_buffer_left(buffer));
    }
    comm->ssrc = bPer_read_4bytes(buffer);
    comm->payloadLen = payload_len-4;
    bPer_read_bytes(buffer,(char*)comm->payload,comm->payloadLen);

	return BPer_Ok;
}

int32_t bPer_encode_rtcpCommon(BPerRtcpCommon* comm,BPerBuffer *buffer){
	 return bPer_error_wrap(ERROR_RTC_RTCP, "not implement");
}


int32_t bPer_decode_header_rtcpCommon(BPerRtcpCommon* comm,BPerBuffer *buffer)
{
	if(comm==NULL||buffer==NULL) return 1;
    if (!bPer_buffer_require(buffer,BPer_RtcpHeader_Length + 4)) {
        return bPer_error_wrap(ERROR_RTC_RTCP, "require %d", BPer_RtcpHeader_Length + 4);
    }


    bPer_decode_rtcpHeader(&comm->header,buffer->head);
    bPer_buffer_skip(buffer,BPer_RtcpHeader_Length);

    int32_t payload_len = comm->header.length * 4;
    if (payload_len > bPer_buffer_left(buffer)) {
        return bPer_error_wrap(ERROR_RTC_RTCP,
                "header require payload len=%u, buffer left=%u", payload_len, bPer_buffer_left(buffer));
    }
    comm->ssrc = bPer_read_4bytes(buffer);

    return BPer_Ok;
}

int32_t bPer_encode_header_rtcpCommon(BPerRtcpCommon* comm,BPerBuffer *buffer)
{
	if(comm==NULL||buffer==NULL) return 1;
    if(! bPer_buffer_require(buffer,BPer_RtcpHeader_Length + 4)) {
        return bPer_error_wrap(ERROR_RTC_RTCP, "require %d", BPer_RtcpHeader_Length + 4);
    }

    bPer_encode_rtcpHeader(&comm->header,buffer);

    bPer_write_4bytes(buffer,comm->ssrc);

    return BPer_Ok;
}
int32_t bPer_encode_header_rtcpHeader(BPerRtcpHeader* header,uint32_t ssrc,BPerBuffer *buffer)
{
	if(header==NULL||buffer==NULL) return 1;
    if(! bPer_buffer_require(buffer,BPer_RtcpHeader_Length + 4)) {
        return bPer_error_wrap(ERROR_RTC_RTCP, "require %d", BPer_RtcpHeader_Length + 4);
    }

    bPer_encode_rtcpHeader(header,buffer);

    bPer_write_4bytes(buffer,ssrc);
    return BPer_Ok;
}

uint64_t bPer_get_rtcpCommon_nb_bytes(BPerRtcpCommon* comm)
{
    return BPer_RtcpHeader_Length + 4 + comm->payloadLen;
}

void bPer_create_rtcpCommon(BPerRtcpCommon* comm){
	if(comm==NULL) return;

}

void bPer_destroy_rtcpCommon(BPerRtcpCommon* comm){
	if(comm==NULL) return;
	bPer_destroy_rtcpSR(comm);
	bPer_destroy_rtcpRR(comm);
	bPer_destroy_rtcpNack(comm);
	bPer_destroy_rtcpRpsi(comm);
	bPer_destroy_rtcptwcc(comm);
	bPer_destroy_rtcpSli(comm);
	comm->data=NULL;
}

